#include "dkglObjModel.h"

namespace DKGL
{
	ObjModel::ObjModel(const String& name, const String& filepath):
		Mesh(name),
		_vertCount(0)
	{
		load(filepath);
		genDisplayList();
	}


	ObjModel::~ObjModel()
	{
		if (displayListId)
		{
			glDeleteLists(displayListId, 1);
		}
	}


	void ObjModel::renderImpl()
	{
		Mesh::renderImpl();
		//_materialPtr->begin();
        glCallList(displayListId);  
	}


	void ObjModel::load(const String& filename)
	{
		if (!LoadModel(filename))
		{
			throw runtime_error("");
		}

		_vertCount = m_f.size()*3;

		vertexBuf.alloc(_vertCount);
		normalBuf.alloc(_vertCount);

		deque<COBJFace>::iterator faceIter(m_f.begin());
		deque<COBJFace>::iterator faceIterEnd(m_f.end());

		size_t i = 0;
		for (;faceIter!=faceIterEnd;++faceIter)
		{
			for (size_t j=0;j<3;j++)
			{
				vertexBuf.set(i, m_v[faceIter->m_vID].x, m_v[faceIter->m_vID].y, m_v[faceIter->m_vID].z);
				normalBuf.set(i, m_vn[faceIter->m_vnID].x, m_vn[faceIter->m_vnD].y, m_vn[faceIter->m_vnID].z);
				i++;
			}
		}
	}


	void ObjModel::genDisplayList()
	{
		displayListId = glGenLists(1);
	    if(!displayListId) 
			assert(0);

        glEnableClientState(GL_NORMAL_ARRAY);
	    glEnableClientState(GL_VERTEX_ARRAY);
        //glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glNormalPointer(GL_FLOAT, 0, normalBuf.get());
	    glVertexPointer(3, GL_FLOAT, 0, vertexBuf.get());
        //glTexCoordPointer(2, GL_FLOAT, 0, texcoordBuf.get());

        glNewList(displayListId, GL_COMPILE);
        {
			glDrawArrays(GL_TRIANGLES, 0, _vertCount);
        }
        glEndList();

	    glDisableClientState(GL_VERTEX_ARRAY);	
	    glDisableClientState(GL_NORMAL_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	}


	MeshPtr ObjModelCreator::create(const String& name, const Arguments& args)
	{
		try
		{
			return MeshPtr(new ObjModel(name, any_cast<String>(args[0])));
		}
		catch (const boost::bad_any_cast&)
		{
			throw std::invalid_argument("");
		}
	}
}